package tablaSimbolos;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

public class EntradaMetodo {
	//corresponde a los PARAMETROS FORMALES, no a las variables locales
	private Hashtable<String, EntradaVariable> TP;
	private Queue<EntradaVariable> colaP,colaBackup; //para chequear el orden de los parametros
	private String tipo,nombre,label;	
	private boolean definido,declarado;
	private int offset,offParam;
	
	public EntradaMetodo(String n,String t){
		tipo = t;
		nombre = n;
		TP = new Hashtable<String, EntradaVariable>();
		colaP = new LinkedList<EntradaVariable>();
		colaBackup = new LinkedList<EntradaVariable>();
		definido=false;
		declarado = true;
		offParam = 1; //arranca en 1 por el 'this' del registro de activacion
		
	}
	
	
	public String getLabel() {
		return label;
	}

	
	public int getOffParam() {
		return offParam;
	}


	public void setOffParam(int offParam) {
		this.offParam = offParam;
	}


	public void setLabel(String label) {
		this.label = label;
	}


	public int getOffset(){
		return offset;
	}
	public void setOffset(int off){
		offset = off;
	}
	public void setTipo(String t){
		tipo=t;
	}
	public String getTipo(){
		return tipo;
	}
	
	public boolean estaDeclarado(){
		return declarado;
	}
	
	public void declarar(boolean b){
		declarado = b;
	}
	
	public boolean estaDefinido(){
		return definido;
	}
	
	public void definir(boolean b){
		definido = b;
	}
	public void setNombre(String n){
		nombre = n;
	}
	public String getNombre(){
		return nombre;
	}
	public EntradaVariable getParam(String p){
		return TP.get(p);
	}
	public String getParamTipo(String p){
		EntradaVariable ent = TP.get(p);
		if(ent!=null)
			return ent.getTipo();
		else
			return null;
	}
	public int getCantParams(){
		return TP.size();
	}
	
	public String getParamValor(String p){
		EntradaVariable ent = TP.get(p);
		if(ent!=null)
			return ent.getValor();
		else
			return null;
	}
	public void setParamTipo(String p,String t){
		EntradaVariable ent = TP.get(p);
		if(ent!=null){
			ent.setTipo(t);
		}
		//si no existe, deberia saltar error? mas adelante se ver�
	}
	public void setParamValor(String p,String v){
		EntradaVariable ent = TP.get(p);
		if(ent!=null){
			ent.setTipo(v);
		}
		//si no existe, deberia saltar error? mas adelante se ver�
	}
	
	public void agregarParam(String lex, String t){
		EntradaVariable nueva = new EntradaVariable(t,lex);
		nueva.setOffset(offParam++);
		TP.put(lex,nueva);
		colaP.add(nueva);
		colaBackup.add(nueva);
	}
	public EntradaVariable returnParamInvoc(){
		return colaP.poll();
		
	}
	public boolean chequearParamDef(String n,String t){
		EntradaVariable enCola = colaP.poll();
		return enCola != null && 
			   enCola.getTipo().equals(t) &&
			   enCola.getNombre().equals(n);
	}	
	public boolean colaParamVacia(){
		boolean resul = false;
		if (colaP.peek() == null){//esta vacia			
			resul = true;
		}		
		restaurar(); //se asume que este metodo se usa al final de los chequeos de 
					//parametros, por lo que siempre se restaurar�
		return resul;
	}
	public void fixOffsets(){
		for (EntradaVariable v : TP.values()){
			v.setOffset(offParam-v.getOffset());
		}
	}
	private void restaurar(){
		Iterator<EntradaVariable> it = colaBackup.iterator();
		while(it.hasNext()){
			EntradaVariable param = it.next();
			colaP.add(param);
		}
	}
	
}
